菜单国际化实践:注意特殊情况defineXXX
实战:配置菜单项的国际化
上一节介绍了 i18n 的三种使用方式,本节通过实际操作来完成所有菜单项的国际化配置。以"组件示例"菜单项为例,演示完整的配置流程。
使用 i18n Ally 插件提取文案
在 VS Code 中安装 i18n Ally 插件后,国际化配置的流程变得非常高效:
- 选中需要国际化的文本(如"组件示例")
- 按下
Cmd+.或Ctrl+.触发提取 - 输入 i18n key,例如
pages.components - 选择替换方式(创建新路径还是复用已有路径)
对于与页面相关的翻译,推荐使用 pages 作为命名空间前缀,后面跟上页面或功能名称:
pages.components -> 组件示例 / Components
pages.iconList -> 图标示例 / Icons
pages.notice -> 通知组件 / Notice
pages.iconPicker -> 图标选择器 / Icon Picker
pages.message -> 通知消息 / Messages
text
翻译与校对
i18n Ally 插件提供了自动翻译功能,但机器翻译的结果不一定准确。例如 components 可能被翻译为"成分"而非"组件示例"。对于翻译量较大的项目,可以先批量自动翻译,再逐条校对;对于翻译量小的场景,建议直接手动编辑。
在插件的左侧面板中,找到对应的 key,点击编辑按钮即可修改翻译内容。保存后切换浏览器语言即可验证效果。
defineXXX 的特殊性
为什么 definePageMeta 中不能用 Composition API
这是本节的核心知识点。definePageMeta 是一个编译器宏(Compiler Macro),它的工作原理决定了它无法使用 Composition API:
// definePageMeta 在 setup 函数之外执行
// 此时 useI18n() 还未被初始化,会报 "t is not defined"
definePageMeta({
// 错误写法:无法在这里使用 t() 或 $t()
title: t('pages.components') // ReferenceError: t is not defined
// 正确写法:直接使用字符串 key
title: 'pages.components'
})
typescript
在文件路由(如 unplugin-vue-router)的自动路由模式下,还有额外的限制:自动路由插件不认识从 vue-i18n 导入的 t 函数,即使局部导入也解析不了。因此在 definePageMeta 中只能妥协使用字符串。
defineProps 中的选择
在 defineProps 中,理论上也不能使用 Composition API。但有些团队会选择在默认值中写一个箭头函数形式的 t 调用:
defineProps({
title: {
type: String,
// 这种写法仅为了兼容 i18n Ally 插件的显示
default: () => t('pages.components')
}
})
typescript
这种做法的唯一目的是让 VS Code 的 i18n Ally 插件在编辑器中直接展示翻译后的中文文本,而非显示一个难以理解的 key 字符串。i18n 真正生效的地方是在模板中通过 $t() 包裹 title 的位置。
建议的统一策略
| 位置 | 推荐做法 | 原因 |
|---|---|---|
<template> | $t('key') | 标准用法,插件直接支持 |
<script setup> 普通代码 | const { t } = useI18n() | Composition API 标准调用 |
defineProps | 字符串 'key' | 保持一致性,避免混淆 |
definePageMeta | 字符串 'key' | 编译器宏限制,无法使用 API |
统一建议:在 defineProps 和 definePageMeta 中一律使用字符串 key,不在编译器宏中使用任何 t 函数。这种做法虽然失去了编辑器中的即时翻译预览,但代码更清晰、更不容易出错。
验证国际化效果
配置完成后,在浏览器中切换语言来验证所有菜单项是否正确翻译:
- 切换到英文,检查所有菜单项是否变为英文
- 切换回中文,确认中文显示正确
- 特别注意子菜单项(如图标选择器、消息通知)是否也跟随切换
如果发现某些菜单项没有切换,通常原因是遗漏了该页面的 title 配置,或者在 Menu/SubMenu 组件中没有对 meta.title 进行 $t() 包裹。
关键要点总结
- 编译器宏(
definePageMeta、defineProps)在 setup 函数之外执行,无法使用useI18n等 Composition API - i18n Ally 插件的
t函数兼容写法纯粹是为了编辑器体验,不影响运行时行为 - 推荐统一策略:编译器宏中只用字符串 key,模板中用
$t(),script 中用useI18n - 翻译后必须手动校对,机器翻译(如将
components译为"成分")可能不符合业务语义
↑